
#include "copyright.h"

#include "syscall.h"
#include "HeadCustomer.h"

void finishedAgent(){

	/*if(GetMonitor(ManagerFinishedName, ManagerFinishedNameLength, 0) == 1){
		Exit(1);
	}*/

}


int headCustomerInitialize(){


	int custNum;
	int groupNum;
	

	AcquireLock(headCustomerIndexLockName,headCustomerIndexLockNameLength);
		custNum = GetMonitor(nextHeadCustomerName, nextHeadCustomerNameLength, 0);
		groupNum = custNum;
		SetMonitor(nextHeadCustomerName, nextHeadCustomerNameLength, custNum + 1, 0);
		SetMonitor(numCustomersName, numCustomersNameLength, GetMonitor(numCustomersName, numCustomersNameLength, 0) + 1, 0);
		/*SetMonitor(custCounterName, custCounterNameLength, GetMonitor(custCounterName, custCounterNameLength, 0) + 1, 0);*/
	ReleaseLock(headCustomerIndexLockName,headCustomerIndexLockNameLength);


	/*Head Customers Regular Customer Data (because hes a customer too)*/	
	
	
	SetMonitor(customerNumberName, customerNumberNameLength, custNum*4, custNum*4);
	SetMonitor(customerGroupNumberName, customerGroupNumberNameLength, groupNum, custNum);
	SetMonitor(customerWantsPopcornName, customerWantsPopcornNameLength, -1, custNum);
	SetMonitor(customerWantsSodaName, customerWantsSodaNameLength, -1, custNum);
	SetMonitor(customerNeedsBathroomName, customerNeedsBathroomNameLength, -1, custNum);
	SetMonitor(customerIsHeadCustomerName, customerIsHeadCustomerNameLength, -1, custNum);
	SetMonitor(customerSeatNumberName, customerSeatNumberNameLength, -1, custNum);
	SetMonitor(customerHasPopcornName, customerHasPopcornNameLength, -1, custNum);
	SetMonitor(customerHasSodaName, customerHasSodaNameLength, -1, custNum);
	
	/* Head Customer Data */
	SetMonitor(groupSizeName, groupSizeNameLength, 3, groupNum);
	SetMonitor(groupPopcornSizeName, groupPopcornSizeNameLength, -1, groupNum);
	SetMonitor(groupSodaSizeName, groupSodaSizeNameLength, -1, groupNum);
	SetMonitor(groupBathroomSizeName, groupBathroomSizeNameLength, -1, groupNum);
	SetMonitor(groupMoneyName, groupMoneyNameLength, 105, groupNum);
	SetMonitor(groupTicketsName, groupTicketsNameLength, -1, groupNum);
	SetMonitor(headCustomerNumberName, headCustomerNumberNameLength, custNum*4, groupNum);
	SetMonitor(customerStateName, customerStateNameLength, -1, groupNum);
	
	return custNum;
}


void headCustomer(){
	int temp;
	int myIndex;
	int flag;
	int myTicketClerk;
	int shortestTicketClerkLine;
	int shortestTicketClerkLineLength;
	int shortestConcessionLine;
	int shortestConcessionLineLength;
	int i;
	int myTicketTaker;
	int shortestTicketTakerLine ; 
	int shortestTicketTakerLineLength;
	int foundRow;
	int seatNumber;
	int tempGroupSize;
	int j;
	int k;
	int myConcessionClerk;
	int tempRegCustomer;
	int tmp;
	int printNumber;
	int printGroup;
	int grSize;
	
	myIndex = headCustomerInitialize();
	printNumber = GetMonitor(headCustomerNumberName, headCustomerNumberNameLength, myIndex);
	printGroup = myIndex;/*GetMonitor(customerGroupNumberName, customerGroupNumberNameLength, printNumber);*/
	grSize = GetMonitor(groupSizeName, groupSizeNameLength,myIndex);
	
	/*Printing("Before AcquireLockd HeadCustomer Lock %i\n", ConsoleOutput, headCustomerIndexLock,0);*/
	
	 flag = 1;
		
	/*printf("HCust%i: I am a head customer with groupsize = %i\n", myIndex, grSize + 1);*/
	
	/*BEGIN: Customer - TicketClerk Interaction*/
	
	myTicketClerk = -1; /* index = -1 */
	
	while(flag){
		/*printf("HCust%i: while flagging a ticket clerk\n", myIndex);*/
		/*Printing("Customer %i of group %i \0", ConsoleOutput, printNumber, printGroup);*/
		/*Printing("trying to AcquireLock lock %i!\n", ConsoleOutput, ticketClerkLineLock, 0);*/
		AcquireLock(ticketClerkLineLockName, ticketClerkLineLockNameLength);/* Lock for choosing a line */
		/*Printing("Customer %i AcquireLock lock %i!\n", ConsoleOutput, printNumber, ticketClerkLineLock);*/
		
		/* look for a clerk in the NOT_BUSY state */
		for(i = 0; i < MAX_TC; i++){
			/* need to have a check to see if the clerk "exists" and is NOT_BUSY */
			if(GetMonitor(ticketClerkStateName,ticketClerkStateNameLength,i) == 0){
				/* dont have to wait, just go to clerk */
				myTicketClerk = i;
				SetMonitor(ticketClerkStateName,ticketClerkStateNameLength,1,i);
				
				Printing("Customer %i in Group %i \0", ConsoleOutput, printNumber, printGroup);
				
				Printing("is walking up to TicketClerk %i to buy %i tickets\n", ConsoleOutput, myTicketClerk, grSize + 1);
				
				flag = 0;
				break;
			}
		}
		
		/* if I dont have a clerk (myTicketClerk = -1), choose shortest line */
		if(myTicketClerk == -1){
		
			/*printf("HCust%i: Finding the shortest line\n", myIndex);*/
			shortestTicketClerkLine = 0; /* index = 0 */
			shortestTicketClerkLineLength = GetMonitor(ticketClerkLineCountName, ticketClerkLineCountNameLength,0);
			
			/* need to find a starting line that isnt on break */
			for(i = 0; i < MAX_TC; i++){
				if(GetMonitor(ticketClerkStateName,ticketClerkStateNameLength,i) == 1){
					/*printf("HCust%i: attempting to AcquireLock TC%is lock to get shortest line\n", myIndex, i);*/
					/*Printing("Customer %i attempting to AcquireLock lock %i to get shortest line1\n", ConsoleOutput, myIndex, ticketClerkBreakLock[i]);*/
					AcquireLock(ticketClerkBreakLockName[i], ticketClerkBreakLockNameLength[i]);
					/*Printing("Customer %i AcquireLockd lock %i to get shortest line1\n", ConsoleOutput, myIndex, ticketClerkBreakLock[i]);*/
					if(GetMonitor(ticketClerkBreakName, ticketClerkBreakNameLength, i) == 0){
						/*printf("HCust%i: found an off break line at TC%i\n", myIndex, i);*/
						shortestTicketClerkLine = i;
						shortestTicketClerkLineLength = GetMonitor(ticketClerkLineCountName,ticketClerkLineCountNameLength,i);
					}
					/*Printing("Customer %i attempting to ReleaseLock lock %i to get shortest line1\n", ConsoleOutput, myIndex, ticketClerkBreakLock[i]);*/
					/*Printing("HC%i: is there anybody going to listen to my story %i\n", ConsoleOutput, myIndex, i);*/
					ReleaseLock(ticketClerkBreakLockName[i], ticketClerkBreakLockNameLength[i]);
					/*Printing("Customer %i ReleaseLockd lock %i to get shortest line1\n", ConsoleOutput, myIndex, ticketClerkBreakLock[i]);*/
				}
			}
			
			
			
			for(i = 0; i < MAX_TC; i++){
			
				if(GetMonitor(ticketClerkStateName,ticketClerkStateNameLength,i) == 1){
					/*Printing("Customer %i attempting to AcquireLock lock %i to get shortest line2\n", ConsoleOutput, myIndex, ticketClerkBreakLock[i]);*/
					AcquireLock(ticketClerkBreakLockName[i], ticketClerkBreakLockNameLength[i]);
					/*Printing("Customer %i AcquireLockd lock %i to get shortest line2\n", ConsoleOutput, myIndex, ticketClerkBreakLock[i]);*/
					if(shortestTicketClerkLineLength >= GetMonitor(ticketClerkLineCountName,ticketClerkLineCountNameLength,i) && GetMonitor(ticketClerkBreakName, ticketClerkBreakNameLength,i) == 0){ /* if theres a shorter line than current line */
						/*printf("HCust%i: found a shorter line at TC%i\n", myIndex, i);*/
						shortestTicketClerkLine = i;
						shortestTicketClerkLineLength = GetMonitor(ticketClerkLineCountName,ticketClerkLineCountNameLength,i);
					}
					/*Printing("Customer %i attempting to ReleaseLock lock %i to get shortest line2\n", ConsoleOutput, myIndex, ticketClerkBreakLock[i]);*/
					/*Printing("HC%i: she promises the earth to me %i\n", ConsoleOutput, myIndex, i);*/
					ReleaseLock(ticketClerkBreakLockName[i], ticketClerkBreakLockNameLength[i]);
					/*Printing("Customer %i ReleaseLockd lock %i to get shortest line2\n", ConsoleOutput, myIndex, ticketClerkBreakLock[i]);*/
				}
			}
			
			/* Steps
			1. I must have the shortest line at this point 
			2. Get in that line 
			3. Sleep and give up the lock, will reAcquireLock the lock when signaled */
			
			
			/*printf("HCust%i: Getting in a line\n", myIndex);*/
			myTicketClerk = shortestTicketClerkLine;
			Printing("Customer %i in Group %i is getting \0", ConsoleOutput, printNumber, printGroup);
			Printing("in TicketClerk line %i\n", ConsoleOutput,myTicketClerk, 0);
			tmp = GetMonitor(ticketClerkLineCountName, ticketClerkLineCountNameLength, myTicketClerk);
			SetMonitor(ticketClerkLineCountName, ticketClerkLineCountNameLength, tmp + 1, myTicketClerk);
			
			Wait(ticketClerkLineConditionVariableName[myTicketClerk], ticketClerkLineConditionVariableNameLength[myTicketClerk], ticketClerkLineLockName, ticketClerkLineLockNameLength);
			finishedAgent();
	
			
			/*printf("HCust%i: i will now try to take TC%is break lock and i have the ticket clerk line lock\n", myIndex, myTicketClerk);*/
			/*Printing("Customer %i attempting to AcquireLock lock %s to check break\n", ConsoleOutput, myIndex, ticketClerkBreakLockName[myTicketClerk]);*/
			AcquireLock(ticketClerkBreakLockName[myTicketClerk], ticketClerkBreakLockNameLength[myTicketClerk]);
			/*Printing("Customer %i AcquireLockd lock %i to check break\n", ConsoleOutput, myIndex, ticketClerkBreakLock[myTicketClerk]);*/
			/*printf("HCust%i: TC%is break lock AcquireLockd\n", myIndex, myTicketClerk);*/
			if(GetMonitor(ticketClerkBreakName, ticketClerkBreakNameLength,myTicketClerk) == 1){
				
				Printing("Customer %i in Group %i sees TicketClerk \0", ConsoleOutput, printNumber, printGroup);
				Printing("%i is on break.\n", ConsoleOutput, myTicketClerk, 0);		
				
				SetMonitor(ticketClerkLineCountName, ticketClerkLineCountNameLength, GetMonitor(ticketClerkLineCountName, ticketClerkLineCountNameLength, myTicketClerk) - 1, myTicketClerk);
				
				ReleaseLock(ticketClerkLineLockName, ticketClerkLineLockNameLength);
				/*Printing("Customer %i attempting to ReleaseLock lock %i to check break1\n", ConsoleOutput, myIndex, ticketClerkBreakLock[myTicketClerk]);*/
				ReleaseLock(ticketClerkBreakLockName[myTicketClerk], ticketClerkBreakLockNameLength[myTicketClerk]);
				/*Printing("Customer %i ReleaseLockd lock %i to check break1\n", ConsoleOutput, myIndex, ticketClerkBreakLock[myTicketClerk]);*/
				
				myTicketClerk = -1;
			} else if(GetMonitor(ticketClerkBreakName, ticketClerkBreakNameLength,myTicketClerk) == 2){
				/*printf("HCust%i: my TC%i is taking too long, gotta find a new line\n", myIndex, myTicketClerk);*/
				SetMonitor(ticketClerkLineCountName, ticketClerkLineCountNameLength, GetMonitor(ticketClerkLineCountName, ticketClerkLineCountNameLength, myTicketClerk) - 1, myTicketClerk);

				
				if(GetMonitor(ticketClerkLineCountName,ticketClerkLineCountNameLength,myTicketClerk) == 0){
					/*printf("HCust%i: TC%i line count == 0\n", myIndex, myTicketClerk);*/
					SetMonitor(ticketClerkBreakName, ticketClerkBreakNameLength, 0, myTicketClerk);
				}
				
				/*Printing("Customer %i attempting to ReleaseLock lock %i to check break2\n", ConsoleOutput, printNumber, ticketClerkLineLock);*/
				ReleaseLock(ticketClerkLineLockName,ticketClerkLineLockNameLength);
				/*Printing("Customer %i attempting to ReleaseLock lock %i to check break2\n", ConsoleOutput, myIndex, ticketClerkBreakLock[myTicketClerk]);*/
				ReleaseLock(ticketClerkBreakLockName[myTicketClerk], ticketClerkBreakLockNameLength[myTicketClerk]);
				/*Printing("Customer %i ReleaseLockd lock %i to check break2\n", ConsoleOutput, myIndex, ticketClerkBreakLock[myTicketClerk]);*/
				
				myTicketClerk = -1;
			} else {
				/*printf("HCust%i: my TC%i isnt on break and doesnt have a huge line. onward!\n", myIndex, myTicketClerk);*/
				flag = 0;
				/*Printing("Customer %i YO WUDDUP\n", ConsoleOutput, printNumber, 0);*/
				/*Printing("Customer %i attempting to ReleaseLock lock %i to check break3\n", ConsoleOutput, myIndex, ticketClerkBreakLock[myTicketClerk]);*/
				ReleaseLock(ticketClerkBreakLockName[myTicketClerk], ticketClerkBreakLockNameLength[myTicketClerk]);
				/*Printing("Customer %i ReleaseLockd lock %i to check break3\n", ConsoleOutput, myIndex, ticketClerkBreakLock[myTicketClerk]);*/
			}
		}
	}
	
	flag = 1;
	/*printf("HCust%i: releasing the kraken on TC%i \n", myIndex, myTicketClerk);*/
	ReleaseLock(ticketClerkLineLockName, ticketClerkLineLockNameLength);
	/*Printing("Customer %i acquiring lock %i\n", ConsoleOutput, printNumber, ticketClerkLock[myTicketClerk]);*/
	
	

		Printing("The size is %i.\n", ConsoleOutput, ticketClerkLockNameLength[myTicketClerk], 0);
	
	
	if(!ticketClerkLockName[myTicketClerk]){
		Printing("This is null.\n", ConsoleOutput, 0, 0);
	}
	
	
	AcquireLock((char *)(ticketClerkLockName[myTicketClerk]),(int)(ticketClerkLockNameLength[myTicketClerk]));
	
	
	
	
	/*Printing("Customer %i AcquireLockd lock %i\n", ConsoleOutput, printNumber, ticketClerkLock[myTicketClerk]);*/
	
	/*Printing("Customer %i acquiring lock %i\n", ConsoleOutput, printNumber, ticketClerkBreakLock[myTicketClerk]);*/
	AcquireLock(ticketClerkBreakLockName[myTicketClerk], ticketClerkBreakLockNameLength[myTicketClerk]);
	/*Printing("Customer %i AcquireLockd lock %i\n", ConsoleOutput, printNumber, ticketClerkBreakLock[myTicketClerk]);*/
	
	/*STEP 1: Customer-TicketClerk, Sets the global variable indicating the number of tickets he wants to buy.*/
	/*printf("HCust%i: Hello, TC%i I need %i tickets\n", myIndex, myTicketClerk, (grSize + 1));*/
	Printing("Customer %i needs tickets from ticketClerk %i\n", ConsoleOutput, printNumber, myTicketClerk);
	SetMonitor(ticketClerkNumToSellName, ticketClerkNumToSellNameLength, (grSize + 1), myTicketClerk);
	
	
	Signal(ticketClerkConditionVariableName[myTicketClerk], ticketClerkConditionVariableNameLength[myTicketClerk],ticketClerkLockName[myTicketClerk],ticketClerkLockNameLength[myTicketClerk]);
	ReleaseLock(ticketClerkBreakLockName[myTicketClerk], ticketClerkBreakLockNameLength[myTicketClerk]);
	Wait(ticketClerkConditionVariableName[myTicketClerk], ticketClerkConditionVariableNameLength[myTicketClerk],ticketClerkLockName[myTicketClerk],ticketClerkLockNameLength[myTicketClerk]);
	finishedAgent();
	AcquireLock(ticketClerkBreakLockName[myTicketClerk], ticketClerkBreakLockNameLength[myTicketClerk]);

	/*STEP 2: Customer-TicketClerk, Customer hands out the cash.*/
	Printing("Customer %i in Group %i in TicketClerk line \0", ConsoleOutput,printNumber, printGroup);
	Printing("%i is paying %i for tickets\n", ConsoleOutput, myTicketClerk, (grSize + 1)*12);
	
	Signal(ticketClerkConditionVariableName[myTicketClerk], ticketClerkConditionVariableNameLength[myTicketClerk],ticketClerkLockName[myTicketClerk],ticketClerkLockNameLength[myTicketClerk]);
	ReleaseLock(ticketClerkBreakLockName[myTicketClerk], ticketClerkBreakLockNameLength[myTicketClerk]);
	Wait(ticketClerkConditionVariableName[myTicketClerk], ticketClerkConditionVariableNameLength[myTicketClerk],ticketClerkLockName[myTicketClerk],ticketClerkLockNameLength[myTicketClerk]);
	finishedAgent();
	AcquireLock(ticketClerkBreakLockName[myTicketClerk], ticketClerkBreakLockNameLength[myTicketClerk]);
	
	/*STEP 3: Customer-TicketClerk, After the ticket clerks sells the tickets, he takes the tickts (sets groupTickets)*/
	
	Printing("Customer %i is paying %i for tickets\n", ConsoleOutput, printNumber, (grSize + 1)*12);
	SetMonitor(groupTicketsName,groupTicketsNameLength, grSize + 1, myIndex);

	Signal(ticketClerkConditionVariableName[myTicketClerk], ticketClerkConditionVariableNameLength[myTicketClerk],ticketClerkLockName[myTicketClerk],ticketClerkLockNameLength[myTicketClerk]);
	
	Printing("Customer %i in Group %i is \0", ConsoleOutput, printNumber, printGroup);
	Printing("leaving TicketClerk %i\n", ConsoleOutput, myTicketClerk, 0);
	ReleaseLock(ticketClerkBreakLockName[myTicketClerk], ticketClerkBreakLockNameLength[myTicketClerk]);
	ReleaseLock(ticketClerkLockName[myTicketClerk],ticketClerkLockNameLength[myTicketClerk]);
	
	/*printf("HCust%i: I have $%i left in my wallet.\n", myIndex, groupMoney[myIndex]);*/
	
	/*END: Customer - TicketClerk Interaction*/
	
	/*BEGIN: HeadCustomer - RegularCustomer Interaction for Concessions*/
	 

	/*STEP 1: HeadCustomer - RegularCustomer, Tells all of his friends that hes going to order food for them*/
	
	/*Only if the head customer has group members should be AcquireLock the lock, otherwise skip to deciding only for himself*/
	
	if(grSize > 0){
	
		AcquireLock(headCustomerLockName[myIndex],headCustomerLockNameLength[myIndex]);						
		/*Asking each one at a time if they want food, then waiting for the next.*/
		Printing("HeadCustomer %i of Group %i has told the group to proceed.\n", ConsoleOutput, printNumber, printGroup);
		for(i = 0; i < grSize; i++){
			Signal(regularCustomerConditionVariableName[myIndex], regularCustomerConditionVariableNameLength[myIndex], headCustomerLockName[myIndex], headCustomerLockNameLength[myIndex]);
			Wait(headCustomerConditionVariableName[myIndex], headCustomerConditionVariableNameLength[myIndex],headCustomerLockName[myIndex], headCustomerLockNameLength[myIndex]);
			finishedAgent();
		}		
			
		/*STEP 2: The headcustomer decides about food himself, and then tallies the total*/
		SetMonitor(customerWantsPopcornName, customerWantsPopcornNameLength, ((Random()%4 > 0) ? 1 : 0), printNumber);
		SetMonitor(customerWantsSodaName, customerWantsSodaNameLength, ((Random()%4 > 0) ? 1 : 0), printNumber);
		
		Printing("Customer %i in Group %i wants \0",ConsoleOutput, GetMonitor(customerWantsPopcornName, customerWantsPopcornNameLength, myIndex), GetMonitor(customerWantsSodaName, customerWantsSodaNameLength, myIndex));
		Printing("%i popcorn and %i soda.\n", ConsoleOutput, printNumber, printGroup);
		
		SetMonitor(groupPopcornSizeName, groupPopcornSizeNameLength, 0, myIndex);	
		
		for(i = 0; i < GetMonitor(numCustomersName, numCustomersNameLength, 0); i++){
			if(myIndex == GetMonitor(customerGroupNumberName, customerGroupNumberNameLength,i)){
				if(GetMonitor(customerWantsPopcornName, customerWantsPopcornNameLength,i)){
					SetMonitor(groupPopcornSizeName, groupPopcornSizeNameLength, GetMonitor(groupPopcornSizeName, groupPopcornSizeNameLength, myIndex) + 1, myIndex);
				}
			}
		}
		
		SetMonitor(groupSodaSizeName, groupSodaSizeNameLength, 0, myIndex);	
		
		for(i = 0; i < GetMonitor(numCustomersName, numCustomersNameLength, 0); i++){
			if(myIndex == GetMonitor(customerGroupNumberName, customerGroupNumberNameLength,i)){
				if(GetMonitor(customerWantsSodaName, customerWantsSodaNameLength,i)){
					SetMonitor(groupSodaSizeName, groupSodaSizeNameLength, GetMonitor(groupSodaSizeName, groupSodaSizeNameLength, myIndex) + 1, myIndex);
				}
			}
		}
		
		ReleaseLock(headCustomerLockName[myIndex],headCustomerLockNameLength[myIndex]);
	}
	else{
		/*COPIED from STEP 2: The headcustomer decides about food himself only*/
		SetMonitor(customerWantsPopcornName, customerWantsPopcornNameLength, ((Random()%4 > 0) ? 1 : 0), printNumber);
		SetMonitor(customerWantsSodaName, customerWantsSodaNameLength, ((Random()%4 > 0) ? 1 : 0), printNumber);
		SetMonitor(groupPopcornSizeName, groupPopcornSizeNameLength, GetMonitor(customerWantsPopcornName, customerWantsPopcornNameLength, printNumber), myIndex);
		SetMonitor(groupSodaSizeName, groupSodaSizeNameLength, GetMonitor(customerWantsSodaName, customerWantsSodaNameLength, printNumber), myIndex);
		
		
		Printing("Customer %i in Group %i wants \0", ConsoleOutput, printNumber, printGroup);
		Printing("%i popcorn and %i soda.\n",  ConsoleOutput, GetMonitor(customerWantsPopcornName, customerWantsPopcornNameLength, myIndex), GetMonitor(customerWantsSodaName, customerWantsSodaNameLength, myIndex));
		
	}	
	
	
	/*END: HeadCustomer - RegularCustomer Interaction for Concessions*/
	
	/*BEGIN: Customer - ConcessionClerk Interaction*/
	
	if(GetMonitor(groupPopcornSizeName, groupPopcornSizeNameLength,myIndex) > 0 || GetMonitor(groupSodaSizeName, groupSodaSizeNameLength,myIndex) > 0){
	
		myConcessionClerk = -1; /* index = -1 */
		
		while(flag){
			/*printf("HCust%i: while flagging a concession clerk\n", myIndex);*/
			AcquireLock(concessionClerkLineLockName, concessionClerkLineLockNameLength); /* Lock for choosing a line */
			/* look for a clerk in the NOT_BUSY state */
			for(i = 0; i < MAX_CC; i++){
				/* need to have a check to see if the clerk "exists" and is NOT_BUSY */
				if(GetMonitor(concessionClerkStateName, concessionClerkStateNameLength,i) == 0){
					/* dont have to wait, just go to clerk */
					myConcessionClerk = i;
					SetMonitor(concessionClerkStateName, concessionClerkStateNameLength, 1, i);
					Printing("Customer %i in Group %i is walking up to \0", ConsoleOutput, printNumber, printGroup);
					Printing("ConcessionClerk%i to buy %i \0", ConsoleOutput, myConcessionClerk, GetMonitor(groupPopcornSizeName, groupPopcornSizeNameLength, myIndex));
					Printing("popcorn and %i soda.\n", ConsoleOutput, GetMonitor(groupSodaSizeName, groupSodaSizeNameLength, myIndex), 0);
					flag = 0;
					break;
				}
			}
			
			/* if I dont have a clerk (myConcessionClerk = -1), choose shortest line */
			if(myConcessionClerk == -1){
				/*printf("HCust%i: Finding the shortest food line\n", myIndex);*/
				shortestConcessionLine = 0; /* index = 0 */
				shortestConcessionLineLength = GetMonitor(concessionClerkLineCountName,concessionClerkLineCountNameLength,0);
				
				for(i = 0; i < MAX_CC; i++){
					if(GetMonitor(concessionClerkStateName, concessionClerkStateNameLength,i) == 1){
						AcquireLock(concessionClerkBreakLockName[i], concessionClerkBreakLockNameLength[i]);
						if(GetMonitor(concessionClerkBreakName, concessionClerkBreakNameLength,i) == 0){
							shortestConcessionLine = i;
							shortestConcessionLineLength = GetMonitor(concessionClerkLineCountName,concessionClerkLineCountNameLength,i);
						}
						ReleaseLock(concessionClerkBreakLockName[i], concessionClerkBreakLockNameLength[i]);
					}
				}
				
				for(i = 1; i < MAX_CC; i++){
					if(GetMonitor(concessionClerkStateName, concessionClerkStateNameLength,i) == 1){
						AcquireLock(concessionClerkBreakLockName[i], concessionClerkBreakLockNameLength[i]);
						if(shortestConcessionLineLength >= GetMonitor(concessionClerkLineCountName,concessionClerkLineCountNameLength,i) && GetMonitor(concessionClerkBreakName, concessionClerkBreakNameLength,i) == 0){ /* if theres a shorter line than current line and avaliable*/	
							shortestConcessionLine = i;
							shortestConcessionLineLength = GetMonitor(concessionClerkLineCountName,concessionClerkLineCountNameLength,i);
						}
						ReleaseLock(concessionClerkBreakLockName[i], concessionClerkBreakLockNameLength[i]);
					}
				}
				
				/* Steps
				1. I must have the shortest line at this point 
				2. Get in that line 
				3. Sleep and give up the lock, will reAcquireLock the lock when signaled */
				
				/*printf("HCust%i: Getting in a concession line\n", myIndex);*/
				myConcessionClerk = shortestConcessionLine;
				Printing("Customer %i in Group %i is getting \0", ConsoleOutput, printNumber, printGroup);
				Printing("in ConcessionClerk line %i\n", ConsoleOutput, myConcessionClerk, 0);
				
				SetMonitor(concessionClerkLineCountName, concessionClerkLineCountNameLength, GetMonitor(concessionClerkLineCountName, concessionClerkLineCountNameLength, myConcessionClerk) + 1, myConcessionClerk);
				
				Wait(concessionClerkLineConditionVariableName[myConcessionClerk], concessionClerkLineConditionVariableNameLength[myConcessionClerk], concessionClerkLineLockName, concessionClerkLineLockNameLength);
				finishedAgent();
				
				AcquireLock(concessionClerkBreakLockName[myConcessionClerk], concessionClerkBreakLockNameLength[myConcessionClerk]);
				if(GetMonitor(concessionClerkBreakName, concessionClerkBreakNameLength, myConcessionClerk) == 1){
				
					SetMonitor(concessionClerkLineCountName, concessionClerkLineCountNameLength, GetMonitor(concessionClerkLineCountName, concessionClerkLineCountNameLength, myConcessionClerk) - 1, myConcessionClerk);
					/*concessionClerkLineCount[myConcessionClerk]--;*/
					
					Printing("Customer %i in Group %i sees ConcessionClerk \0", ConsoleOutput, printNumber, printGroup);
					Printing("%i is on break.\n",ConsoleOutput, myConcessionClerk, 0);
					ReleaseLock(concessionClerkLineLockName, concessionClerkLineLockNameLength);
					ReleaseLock(concessionClerkBreakLockName[myConcessionClerk], concessionClerkBreakLockNameLength[myConcessionClerk] );
					
					myConcessionClerk = -1;
				} else if(GetMonitor(concessionClerkBreakName, concessionClerkBreakNameLength, myConcessionClerk) == 2){
					
					SetMonitor(concessionClerkLineCountName, concessionClerkLineCountNameLength, GetMonitor(concessionClerkLineCountName, concessionClerkLineCountNameLength, myConcessionClerk) - 1, myConcessionClerk);
					/*concessionClerkLineCount[myConcessionClerk]--;*/
					
					if(GetMonitor(concessionClerkLineCountName, concessionClerkLineCountNameLength, myConcessionClerk) == 0){
					
						SetMonitor(concessionClerkBreakName, concessionClerkBreakNameLength, 0, myConcessionClerk);
					
					}
					
					ReleaseLock(concessionClerkLineLockName, concessionClerkLineLockNameLength);
					ReleaseLock(concessionClerkBreakLockName[myConcessionClerk], concessionClerkBreakLockNameLength[myConcessionClerk]);
					
					myConcessionClerk = -1;
				} else {
					flag = 0;
					ReleaseLock(concessionClerkBreakLockName[myConcessionClerk], concessionClerkBreakLockNameLength[myConcessionClerk]);
				}
			}
		}
		
		flag = 1;
		ReleaseLock(concessionClerkLineLockName, concessionClerkLineLockNameLength);
		AcquireLock(concessionClerkLockName[myConcessionClerk], concessionClerkLockNameLength[myConcessionClerk]);
		AcquireLock(concessionClerkBreakLockName[myConcessionClerk], concessionClerkBreakLockNameLength[myConcessionClerk]);
		
		/*STEP 1: Customer-ConcessionClerk, Tells Concession clerk heres there and read to order.*/
		/*printf("HCust%i: Hello CC%i, I need %i popcorns and %i sodas!\n", myIndex, myConcessionClerk, groupPopcornSize[myIndex], groupSodaSize[myIndex]);*/
		
		
		SetMonitor(concessionClerkPopcornToSellName, concessionClerkPopcornToSellNameLength, GetMonitor(groupPopcornSizeName, groupPopcornSizeNameLength, myIndex),myConcessionClerk);
		SetMonitor(concessionClerkSodaToSellName, concessionClerkSodaToSellNameLength, GetMonitor(groupSodaSizeName, groupSodaSizeNameLength, myIndex),myConcessionClerk);
		
		Signal(concessionClerkConditionVariableName[myConcessionClerk], concessionClerkConditionVariableNameLength[myConcessionClerk], concessionClerkLockName[myConcessionClerk], concessionClerkLockNameLength[myConcessionClerk]);
		ReleaseLock(concessionClerkBreakLockName[myConcessionClerk], concessionClerkBreakLockNameLength[myConcessionClerk] );
		Wait(concessionClerkConditionVariableName[myConcessionClerk], concessionClerkConditionVariableNameLength[myConcessionClerk], concessionClerkLockName[myConcessionClerk], concessionClerkLockNameLength[myConcessionClerk]);
		finishedAgent();
		AcquireLock(concessionClerkBreakLockName[myConcessionClerk], concessionClerkBreakLockNameLength[myConcessionClerk]);
		
		/*STEP 2: Customer-ConcessionClerk, Customer hands out the cash*/
		
		Printing("Customer %i in Group %i in ConcessionClerk line \0", ConsoleOutput, printNumber, printGroup);
		Printing("%i is paying %i for food\n",  ConsoleOutput, myConcessionClerk, (GetMonitor(groupPopcornSizeName, groupPopcornSizeNameLength, myIndex)*5 + GetMonitor(groupSodaSizeName, groupSodaSizeNameLength, myIndex)*4));

		tmp = GetMonitor(groupPopcornSizeName, groupPopcornSizeNameLength, myIndex)*5 + GetMonitor(groupSodaSizeName, groupSodaSizeNameLength, myIndex)*4;
		
		SetMonitor(groupMoneyName, groupMoneyNameLength, GetMonitor(groupMoneyName, groupMoneyNameLength, myIndex) - tmp, myIndex);
		
		/*roupMoney[myIndex] -= GetMonitor(groupPopcornSizeName, groupPopcornSizeNameLength, myIndex)*5 + GetMonitor(groupSodaSizeName, groupSodaSizeNameLength, myIndex)*4;*/
		
		Signal(concessionClerkConditionVariableName[myConcessionClerk], concessionClerkConditionVariableNameLength[myConcessionClerk], concessionClerkLockName[myConcessionClerk], concessionClerkLockNameLength[myConcessionClerk]);
		ReleaseLock(concessionClerkBreakLockName[myConcessionClerk], concessionClerkBreakLockNameLength[myConcessionClerk] );
		Wait(concessionClerkConditionVariableName[myConcessionClerk], concessionClerkConditionVariableNameLength[myConcessionClerk], concessionClerkLockName[myConcessionClerk], concessionClerkLockNameLength[myConcessionClerk]);
		finishedAgent();
		AcquireLock(concessionClerkBreakLockName[myConcessionClerk], concessionClerkBreakLockNameLength[myConcessionClerk]);
		
		/*STEP 3: Customer-ConcessionClerk, After the concession clerks sells the food, he takes the food*/
		Printing("Customer %i in Group %i is leaving \0", ConsoleOutput, printNumber, printGroup);
		Printing("ConcessionClerk%i\n", ConsoleOutput, myConcessionClerk, 0);
		
		/*TODO: Acknowledge that the purchase of food went through somehow.*/

		Signal(concessionClerkConditionVariableName[myConcessionClerk], concessionClerkConditionVariableNameLength[myConcessionClerk], concessionClerkLockName[myConcessionClerk], concessionClerkLockNameLength[myConcessionClerk]);
		
		/*printf("HCust%i: Im done buying food and to the Ticket Taker!\n", myIndex);*/
		ReleaseLock(concessionClerkBreakLockName[myConcessionClerk], concessionClerkBreakLockNameLength[myConcessionClerk] );
		ReleaseLock(concessionClerkLockName[myConcessionClerk], concessionClerkLockNameLength[myConcessionClerk]);
	
		/*printf("HCust%i: I have $%i left in my wallet.\n", myIndex, groupMoney[myIndex]);*/
	}	
	
	/*END: Customer - ConcessionClerk Interaction*/
			
	/*BEGIN: Customer - TicketTaker Interaction*/
	
	while(1){
		myTicketTaker = -1; /* index = -1 */
		/*Printing("Customer %i Part 0\n", ConsoleOutput, printNumber, 0);*/
		while(flag){
			/*printf("HCust%i: about to AcquireLock ticket taker line lock to find a line\n", myIndex);*/
			/*Printing("Customer %i trying to AcquireLock lock at index %i part 1\n", ConsoleOutput, printNumber, ticketTakerLineLock);*/
			AcquireLock(ticketTakerLineLockName, ticketTakerLineLockNameLength);
			/*Printing("Customer %i AcquireLockd lock at index %i part 1\n", ConsoleOutput, printNumber, ticketTakerLineLock);*/
			/*printf("HCust%i: AcquireLockd ticket taker line lock to find a line\n", myIndex);*/
			/* Look to find TixTaker that isnt busy */
			
			/*Printing("Customer %i Part 1\n", ConsoleOutput, printNumber, 0);*/
			for(i = 0; i < MAX_TT; i++){
				/*Printing("Customer %i Part 1.1\n", ConsoleOutput, printNumber, 0);*/
				if(GetMonitor(ticketTakerStateName, ticketTakerStateNameLength, i) == 0){
					/*Printing("Customer %i Part 1.2\n", ConsoleOutput, printNumber, 0);*/
					myTicketTaker = i;
					SetMonitor(ticketTakerStateName, ticketTakerStateNameLength, 1, i);
					Printing("Customer %i in Group %i is walking up to \0", ConsoleOutput, printNumber, printGroup);
					Printing("TicketTaker%i to give %i tickets.\n", ConsoleOutput, myTicketTaker, (grSize + 1));
					flag = 0;
					break;
				}
			}
			
			/*Printing("Customer %i Part 2\n", ConsoleOutput, printNumber, 0);*/
			
			/* TixTakers are all busy, will now look for shortest line */
			if(myTicketTaker == -1){
				/*printf("HCust%i: Finding the shortest ticket taker line\n", myIndex);*/
				shortestTicketTakerLine = 0; 
				shortestTicketTakerLineLength = GetMonitor(ticketTakerLineCountName, ticketTakerLineCountNameLength, 0);
				
				/*Printing("Customer %i Part 2.1\n", ConsoleOutput, printNumber, 0);*/
				
				for(i = 0; i < MAX_TT; i++){
					if(GetMonitor(ticketTakerStateName, ticketTakerStateNameLength, i) == 1){
						AcquireLock(ticketTakerBreakLockName[i], ticketTakerBreakLockNameLength[i]);
						AcquireLock(ticketTakerBreakLockName[i], ticketTakerBreakLockNameLength[i]);
						if(GetMonitor(ticketTakerBreakName, ticketTakerBreakNameLength, i) == 0){
							shortestTicketTakerLine = i;
							shortestTicketTakerLineLength = GetMonitor(ticketTakerLineCountName, ticketTakerLineCountNameLength, i);
						}
						ReleaseLock(ticketTakerBreakLockName[i], ticketTakerBreakLockNameLength[i]);
					}
				}
				
				/*Printing("Customer %i Part 2.2\n", ConsoleOutput, printNumber, 0);*/
				
				for(i = 1; i < MAX_TT; i++){
					if(GetMonitor(ticketTakerStateName, ticketTakerStateNameLength, i) == 1){
						AcquireLock(ticketTakerBreakLockName[i], ticketTakerBreakLockNameLength[i]);
						if((shortestTicketTakerLineLength >= GetMonitor(ticketTakerLineCountName, ticketTakerLineCountNameLength, i)) && GetMonitor(ticketTakerBreakName, ticketTakerBreakNameLength, i) == 0){
							/* Shorter line found, will now update shortest line */
							shortestTicketTakerLine = i;
							shortestTicketTakerLineLength = GetMonitor(ticketTakerLineCountName, ticketTakerLineCountNameLength, i);
						}
						ReleaseLock(ticketTakerBreakLockName[i], ticketTakerBreakLockNameLength[i]);
					}
				}
				
				/*Printing("Customer %i Part 2.3\n", ConsoleOutput, printNumber, 0);*/
				
				/*printf("HCust%i: Getting in a ticket taker line\n", myIndex);*/
				myTicketTaker = shortestTicketTakerLine;
				Printing("Customer %i in Group %i is getting in \0", ConsoleOutput, printNumber, printGroup);
				Printing("TicketTaker line %i\n", ConsoleOutput, myTicketTaker, 0);
				SetMonitor(ticketTakerLineCountName, ticketTakerLineCountNameLength, GetMonitor(ticketTakerLineCountName, ticketTakerLineCountNameLength, myTicketTaker) + 1, myTicketTaker);
				Wait(ticketTakerLineConditionVariableName[myTicketTaker], ticketTakerLineConditionVariableNameLength[myTicketTaker], ticketTakerLineLockName, ticketTakerLineLockNameLength);
				finishedAgent();
				/*printf("HCust%i: reAcquireLockd TT%i ticket taker line lock after waiting in line going to check if hes on break\n", myIndex, myTicketTaker);*/
				
				/*Printing("Customer %i Part 2.4\n", ConsoleOutput, printNumber, 0);*/
				
				AcquireLock(ticketTakerBreakLockName[myTicketTaker], ticketTakerBreakLockNameLength[myTicketTaker]);
				if(GetMonitor(ticketTakerBreakName, ticketTakerBreakNameLength, myTicketTaker) == 1){
					Printing("Customer %i in Group %i sees \0", ConsoleOutput, printNumber, printGroup);
					Printing("TicketTaker %i is on break.\n", ConsoleOutput, myTicketTaker, 0);
					SetMonitor(ticketTakerLineCountName, ticketTakerLineCountNameLength, GetMonitor(ticketTakerLineCountName, ticketTakerLineCountNameLength, myTicketTaker) - 1, myTicketTaker);
					
					ReleaseLock(ticketTakerLineLockName, ticketTakerLineLockNameLength);
					/*printf("HCust%i: ReleaseLockd TT%i ticket taker line lock TTBreak == 1\n", myIndex, myTicketTaker);*/
					ReleaseLock(ticketTakerBreakLockName[myTicketTaker], ticketTakerBreakLockNameLength[myTicketTaker]);
					
					myTicketTaker = -1;
				} else if (GetMonitor(ticketTakerBreakName, ticketTakerBreakNameLength, myTicketTaker) == 2){
					/*printf("HCust%i: my TT%i is taking too long, gotta find a new line\n", myIndex, myTicketTaker);*/
					SetMonitor(ticketTakerLineCountName, ticketTakerLineCountNameLength, GetMonitor(ticketTakerLineCountName, ticketTakerLineCountNameLength, myTicketTaker) - 1, myTicketTaker);
					
					/*Printing("TicketTaker %i is taking too long. ticketTakerLineCount[%i] \0", ConsoleOutput, myTicketTaker, myTicketTaker);*/
					Printing("= %i\n", ConsoleOutput, GetMonitor(ticketTakerLineCountName, ticketTakerLineCountNameLength,myTicketTaker));
					if(GetMonitor(ticketTakerLineCountName, ticketTakerLineCountNameLength,myTicketTaker) == 0){
						/*printf("HCust%i: TT%i line count == 0\n", myIndex, myTicketTaker);*/
						SetMonitor(ticketTakerBreakName, ticketTakerBreakNameLength, 0, myTicketTaker);
					}
					
					ReleaseLock(ticketTakerLineLockName, ticketTakerLineLockNameLength);
					/*printf("HCust%i: ReleaseLockd TT%i ticket taker line lock TTBreak == 2\n", myIndex, myTicketTaker);*/
					ReleaseLock(ticketTakerBreakLockName[myTicketTaker], ticketTakerBreakLockNameLength[myTicketTaker]);
					
					myTicketTaker = -1;
				} else {
					/*printf("HCust%i: my TT%i isnt on break and doesnt have a huge line. onward!\n", myIndex, myTicketTaker);*/
					flag = 0;
					ReleaseLock(ticketTakerBreakLockName[myTicketTaker], ticketTakerBreakLockNameLength[myTicketTaker]);
				}
				/* Cust is now in line waiting to be signaled to come to the counter */
				/*Printing("Customer %i end Part 2\n", ConsoleOutput, printNumber, 0);*/
			}
		}
	
		/*Printing("Customer %i Part 3\n", ConsoleOutput, printNumber, 0);*/
		
		flag = 1;
		/*printf("HCust%i: trying to ReleaseLock ticket taker line lock to start interaction\n", myIndex);*/
		ReleaseLock(ticketTakerLineLockName, ticketTakerLineLockNameLength);
		/*printf("HCust%i: ReleaseLockd ticket taker line lock, trying to AcquireLock TT%i ticket taker lock\n", myIndex, myTicketTaker);*/
		AcquireLock(ticketTakerLockName[myTicketTaker], ticketTakerLockNameLength[myTicketTaker]);
		/*printf("HCust%i: trying to AcquireLock the TT%is break lock\n", myIndex, myTicketTaker);*/
		AcquireLock(ticketTakerBreakLockName[myTicketTaker], ticketTakerBreakLockNameLength[myTicketTaker]);
		/*printf("HCust%i: AcquireLockd the TT%is break lock\n", myIndex, myTicketTaker);*/
		/*printf("HCust%i: TT%i ticket taker lock AcquireLockd\n", myIndex, myTicketTaker);*/
		/* Customer is now at counter */
		
		/*printf("HCust%i: Hello, TT%i I have %i tickets\n", myIndex, myTicketTaker, grSize+1);*/
		SetMonitor(ticketTakerCounterName, ticketTakerCounterNameLength, grSize+1, myTicketTaker);
		
		Signal(ticketTakerConditionVariableName[myTicketTaker],ticketTakerConditionVariableNameLength[myTicketTaker], ticketTakerLockName[myTicketTaker], ticketTakerLockNameLength[myTicketTaker]);
		ReleaseLock(ticketTakerBreakLockName[myTicketTaker], ticketTakerBreakLockNameLength[myTicketTaker]);
		/*printf("HCust%i: about to wait on TT%i ticket taker lock\n", myIndex, myTicketTaker);*/
		Wait(ticketTakerConditionVariableName[myTicketTaker], ticketTakerConditionVariableNameLength[myTicketTaker], ticketTakerLockName[myTicketTaker], ticketTakerLockNameLength[myTicketTaker]);
		finishedAgent();
		/*printf("HCust%i: reAcquireLockd TT%i ticket taker lock\n", myIndex, myTicketTaker);*/
		/*AcquireLock(ticketTakerBreakLockName[myTicketTaker], ticketTakerBreakLockNameLength[myTicketTaker]);*/
		
		/*ReleaseLock(ticketTakerBreakLockName[myTicketTaker], ticketTakerBreakLockNameLength[myTicketTaker]);*/
		if(GetMonitor(ticketTakerCounterName, ticketTakerCounterNameLength,myTicketTaker) == 1){
			SetMonitor(ticketTakerCounterName, ticketTakerCounterNameLength, -1 , myTicketTaker);
			
			
			Signal(ticketTakerConditionVariableName[myTicketTaker],ticketTakerConditionVariableNameLength[myTicketTaker], ticketTakerLockName[myTicketTaker], ticketTakerLockNameLength[myTicketTaker]);
			Printing("Customer %i in Group %i is \0", ConsoleOutput, printNumber, printGroup);
			Printing("leaving TicketTaker%i\n", ConsoleOutput, myTicketTaker, 0);
			ReleaseLock(ticketTakerLockName[myTicketTaker], ticketTakerLockNameLength[myTicketTaker]);
			/*printf("HCust%i: ReleaseLockd TT%i ticket taker lock\n", myIndex, myTicketTaker);*/
			break;
		} else {
			SetMonitor(ticketTakerCounterName, ticketTakerCounterNameLength, -1 , myTicketTaker);
			Signal(ticketTakerConditionVariableName[myTicketTaker],ticketTakerConditionVariableNameLength[myTicketTaker], ticketTakerLockName[myTicketTaker], ticketTakerLockNameLength[myTicketTaker]);
			/*printf("HCust%i: Why is TT%i such a negative nancy?\n", myIndex, myTicketTaker);*/
			ReleaseLock(ticketTakerLockName[myTicketTaker], ticketTakerLockNameLength[myTicketTaker]);
			/*printf("HCust%i: ReleaseLockd TT%i ticket taker lock, trying to AcquireLock ticket taker line lock\n", myIndex, myTicketTaker);*/
			/*Printing("Customer %i trying to AcquireLock lock at index %i part 2\n", ConsoleOutput, printNumber, ticketTakerLineLock);*/
			AcquireLock(ticketTakerLineLockName, ticketTakerLineLockNameLength);
			/*Printing("Customer %i AcquireLockd lock at index %i part 2\n", ConsoleOutput, printNumber, ticketTakerLineLock);*/
			/*printf("\t\t\t\t\t\tHCust%i: going to the lobby\n", myIndex);*/
			Printing("Customer %i in Group %i sees TicketTaker \0", ConsoleOutput, printNumber, printGroup);
			Printing("%i is no longer taking tickets. Going to the lobby.\n", ConsoleOutput, myTicketTaker, 0);
			Printing("Customer %i in Group %i is in the lobby.\n", ConsoleOutput, printNumber, printGroup);
			Wait(lobbyConditionVariableName, lobbyConditionVariableNameLength, ticketTakerLineLockName, ticketTakerLineLockNameLength);
			Printing("Customer %i in Group %i is leaving the lobby.\n", ConsoleOutput, printNumber, printGroup);
			finishedAgent();
			/*printf("HCust%i: reAcquireLockd TT%i ticket taker line lock, about to ReleaseLock\n", myIndex, myTicketTaker);*/
			ReleaseLock(ticketTakerLineLockName, ticketTakerLineLockNameLength);
			/*printf("HCust%i: ReleaseLockd TT%i ticket taker line lock\n", myIndex, myTicketTaker);*/
		}
	}
	
	/*END: Customer - TicketTaker Interaction*/
	/* BEGIN: Customer - Movie Technician Interaction, finding a seat */
	/* 
	A.	find seats
	B.	wait for movie to start/finish
	C.	go bathroom, if needed
	*/
	/*printf("HCust%i: about to AcquireLock movie room lock\n", myIndex);*/
	AcquireLock(movieRoomLockName, movieRoomLockNameLength); /* AcquireLock the room lock */
	/*printf("HCust%i: AcquireLockd movie room lock about to AcquireLock head customer lock\n", myIndex);*/
	AcquireLock(headCustomerLockName[myIndex],headCustomerLockNameLength[myIndex]);	/*printf("HCust%i: i now have head customer lock and movie room lock\n", myIndex);*/
	
	/* 
	A. find seats 
		1.	find row that fits whole group
		2.	tell customers their seat numbers
		3.	add self to row
	*/
	foundRow = 0;
	for(i = 0; i < NUM_ROWS; i++){
		if((GetMonitor(roomName[0], roomNameLength[0], i) + grSize + 1) <= ROW_SIZE){
			foundRow = 1; /* found row */
			seatNumber = GetMonitor(roomName[0], roomNameLength[0], i);
			for(j = 0; j < GetMonitor(numCustomersName, numCustomersNameLength, 0); j++){

				
				if(myIndex == GetMonitor(customerGroupNumberName, customerGroupNumberNameLength,j)){
					/*Rows are numbered with the tens digit = row, ones = column.
					So Seat 3 -> row 0, col 3.  Seat 14 -> row 1, col 4
					*/
					tmp =  i*10+seatNumber;
					SetMonitor(customerSeatNumberName, customerSeatNumberNameLength,tmp,j);
					Printing("Customer %i in Group %i has found the following seat: \0", ConsoleOutput, printNumber, printGroup);
					Printing("row %i and seat %i\n", ConsoleOutput, i, seatNumber);
					
					if(GetMonitor(customerIsHeadCustomerName, customerIsHeadCustomerNameLength,j) == 1){
					/*	printf("HCust%i: Im in seat %i\n", myIndex, customerSeatNumber[j]);*/
					}
					/*SetMonitor(customerSeatNumberName, customerSeatNumberNameLength, seatNumber + 1, 0);*/
					seatNumber++;
					/*seatNumber++;*/
					/*END: HeadCustomer-RegularCustomer Interaction, telling seats*/

				}
			}
			
			SetMonitor(roomName[0], roomNameLength[0], GetMonitor(roomName[0], roomNameLength[0], i) + (grSize + 1), i);
			/*room[i] += (grSize + 1);  add group to row */
			SetMonitor(seatsFilledName, seatsFilledNameLength, GetMonitor(seatsFilledName, seatsFilledNameLength, 0) + (grSize + 1), 0);
			/*seatsFilled += (grSize + 1);*/

			break; /* dont need to keep checking for rows */
		}
	}
	
	/* if no row found
		1. disperse to any available seats
		this is really inefficient, perhaps a better way?
	*/
	if(foundRow == 0){
		tempGroupSize = (grSize + 1);
		for(i = 0; i < NUM_ROWS; i++){
			if(tempGroupSize == 0){ /* the whole group is seated */
				break; 
			} else { /* whole group is not seated CHECK MATH HERE*/
				
				for(j = GetMonitor(roomName[0], roomNameLength[0],i); j < ROW_SIZE; j++){ /* j = seatNumber */
					for(k = 0; k < GetMonitor(numCustomersName, numCustomersNameLength, 0); k++){
						if(myIndex == GetMonitor(customerGroupNumberName, customerGroupNumberNameLength, k) && GetMonitor(customerSeatNumberName,customerSeatNumberNameLength, k) == -1){ /* if customer is in group and does not have a seat */
							
							SetMonitor(customerSeatNumberName,customerSeatNumberNameLength, i*10 + j, k); 
						
							/*customerSeatNumber[k] = i*10 + j;*/
							
							Printing("Customer %i in Group %i has found the following seat: \0", ConsoleOutput,printNumber, printGroup);
							Printing("row %i and seat %i\n", ConsoleOutput, i, j);

							
							if(GetMonitor(customerIsHeadCustomerName, customerIsHeadCustomerNameLength,k) == 1){
								/*printf("HCust%i: Im in seat %i\n", k, customerSeatNumber[k]);*/
							}
							/* ping pong with customer here */
							break; /* seat is filled */
						}
					}
					
					tmp = GetMonitor(roomName[0], roomNameLength[0], i);
					SetMonitor(roomName[0], roomNameLength[0], tmp + tempGroupSize,i);
					/*room[i] += tempGroupSize;*/
					tempGroupSize -= (ROW_SIZE - GetMonitor(roomName[0], roomNameLength[0],i)); /* people leave group to sit */
				}				
			}
		}
		
		/* group should all be seated at this point */
		tmp = GetMonitor(seatsFilledName, seatsFilledNameLength, 0);
		SetMonitor(seatsFilledName, seatsFilledNameLength, tmp +  (grSize + 1), 0);
		/*seatsFilled += (grSize + 1);*/
	}
	
	/*Telling all of the customers their seats.*/
	for(k = 0; k < grSize; k++){
		Signal(regularCustomerConditionVariableName[myIndex], regularCustomerConditionVariableNameLength[myIndex], headCustomerLockName[myIndex], headCustomerLockNameLength[myIndex]);
		/*printf("HCust%i: %i about to wait on head customer lock, just writing movie room lock\n", myIndex, grSize);*/
		Wait(headCustomerConditionVariableName[myIndex], headCustomerConditionVariableNameLength[myIndex],headCustomerLockName[myIndex], headCustomerLockNameLength[myIndex]);
		finishedAgent();
		/*printf("HCust%i: %i reAcquireLockd head customer lock, just writing movie room lock\n", myIndex, grSize);*/
	}
	
	/* B. wait for movie to start and finish */
	/*printf("HCust%i: about to wait on movie room lock\n", myIndex);*/
	Wait(movieRoomConditionVariableName, movieRoomConditionVariableNameLength, movieRoomLockName, movieRoomLockNameLength);
	finishedAgent();
	/*printf("HCust%i: reAcquireLockd movie room lock, about to ReleaseLock movie room lock\n", myIndex);*/
	ReleaseLock(movieRoomLockName, movieRoomLockNameLength);
	/*printf("HCust%i: ReleaseLockd movie room lock\n", myIndex);*/
	
	/* END: Customer finding a seat */
	
	/* BEGIN: Customers in the bathroom*/
	
	if(grSize > 0){

		

		/*STEP 1: Asking each one if they need to go to the bathrrom*/
		for(i = 0; i < grSize; i++){
			Signal(regularCustomerConditionVariableName[myIndex], regularCustomerConditionVariableNameLength[myIndex], headCustomerLockName[myIndex], headCustomerLockNameLength[myIndex]);
			Wait(headCustomerConditionVariableName[myIndex], headCustomerConditionVariableNameLength[myIndex],headCustomerLockName[myIndex], headCustomerLockNameLength[myIndex]);
			finishedAgent();
		}		

		AcquireLock(bathroomLockName[myIndex], bathroomLockNameLength[myIndex]);
		SetMonitor(customerNeedsBathroomName, customerNeedsBathroomNameLength, ((Random()%4 > 0) ? 0 : 1), printNumber);
		/*customerNeedsBathroom[printNumber] = (Random()%4 > 0) ? 0 : 1;*/
		if(GetMonitor(customerNeedsBathroomName, customerNeedsBathroomNameLength,printNumber)){
			/*printf("HCust%i: I need to go to the bathroom!\n",myIndex);*/
		}
		else{
			/*printf("HCust%i: I dont need to go to the bathroom!\n",myIndex);*/

		}
		
		ReleaseLock(bathroomLockName[myIndex], bathroomLockNameLength[myIndex]);

		SetMonitor(groupBathroomSizeName, groupBathroomSizeNameLength, 0, myIndex);
		

		for(i = 0; i < GetMonitor(numCustomersName, numCustomersNameLength, 0); i++){
			if(myIndex == GetMonitor(customerGroupNumberName, customerGroupNumberNameLength,i)){
		
				if(GetMonitor(customerNeedsBathroomName, customerNeedsBathroomNameLength,i)){
					Printing("Customer %i in Group %i is going to the bathroom.\n", ConsoleOutput, printNumber, printGroup);
					AcquireLock(bathroomLockName[myIndex],bathroomLockNameLength[myIndex]);
					tmp = GetMonitor(groupBathroomSizeName, groupBathroomSizeNameLength, myIndex);
					SetMonitor(groupBathroomSizeName, groupBathroomSizeNameLength, tmp + 1, myIndex);
					/*groupBathroomSize[myIndex]++;*/
					ReleaseLock(bathroomLockName[myIndex], bathroomLockNameLength[myIndex]);
				}
			}
		}

		
		/*printf("HCust%i: Ill wait for %i people to go to the bathroon.\n",myIndex,groupBathroomSize[myIndex]);*/

	}
	else{
	
		SetMonitor(customerNeedsBathroomName, customerNeedsBathroomNameLength, (Random()%4 > 0) ? 0 : 1, printNumber);
		if(GetMonitor(customerNeedsBathroomName, customerNeedsBathroomNameLength,printNumber)){
		
			for(i = 0; i < 20; i++){
				/*currentThread->Yield();*/
				Yield();
			}
		
		}
		
		SetMonitor(groupBathroomSizeName, groupBathroomSizeNameLength, 0, myIndex);

	}
	

	
	/*Step 2: Allowing the customers to go to the bathroom, or wait in the lobby*/
	for(i = 0; i < grSize; i++){
	
			Signal(regularCustomerConditionVariableName[myIndex], regularCustomerConditionVariableNameLength[myIndex], headCustomerLockName[myIndex], headCustomerLockNameLength[myIndex]);

			Wait(headCustomerConditionVariableName[myIndex], headCustomerConditionVariableNameLength[myIndex],headCustomerLockName[myIndex], headCustomerLockNameLength[myIndex]);
			finishedAgent();
			
			

	}
	
	
	/*Step 3: Head customer goes to the lobby himself*/
	if(GetMonitor(groupBathroomSizeName, groupBathroomSizeNameLength,myIndex) > 0 && grSize > 0){

		AcquireLock(bathroomLockName[myIndex], bathroomLockNameLength[myIndex]);
		
		tmp = GetMonitor(groupBathroomSizeName, groupBathroomSizeNameLength);
		SetMonitor(groupBathroomSizeName, groupBathroomSizeNameLength, tmp -1,myIndex);
		
		ReleaseLock(bathroomLockName[myIndex], bathroomLockNameLength[myIndex]);
		
		Printing("Customer %i in Group %i is leaving the bathroom.\n", ConsoleOutput, printNumber, printGroup);

	}

	/* END: Customers going to the bathroom */
	
	AcquireLock(counterLockName, counterLockNameLength);
	tmp = GetMonitor(custCounterName, custCounterNameLength, 0);
	SetMonitor(custCounterName, custCounterNameLength, tmp - 4, 0);
	/*custCounter -= 5;*/
	Printing("Customer %i in Group %i has left the movie theater.\n", ConsoleOutput, printNumber, printGroup);
	ReleaseLock(counterLockName, counterLockNameLength);

	ReleaseLock(headCustomerLockName[myIndex], headCustomerLockNameLength[myIndex]);
	
	
}





int main(){
	Printing("Beginning Head Customer\n", ConsoleOutput, 0,0);
	
	headCustomer();
	
	Printing("Ending Head Customer\n", ConsoleOutput, 0,0);

	
	Exit(1);
}


